package mju.cxf.service.impl;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import mju.cxf.OssUtil;
import mju.cxf.constant.MessageConstant;
import mju.cxf.exception.BaseException;
import mju.cxf.exception.PhotoException;
import mju.cxf.service.PhotoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

@Service
@Slf4j
public class PhotoServiceImpl implements PhotoService {
    @Autowired
    private OssUtil ossUtil;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    private static final String IMAGE_PREFIX = "image:"; // Redis Key 前缀
    private static final String[] ALLOWED_EXTENSIONS = {".jpg", ".jpeg", ".png", ".gif", ".bmp"};
    private static final int STATUS_ACTIVE = 1; // 状态码：有效
    private static final int STATUS_UNACTIVE = 0; // 状态码：无效
    private static final long EXPIRATION_TIME = 300 * 1000; // 过期时间（单位：毫秒）

    /**
     * A图片上传回显
     *
     * @param file 文件
     * @return 文件资源定位符
     */
    @Override
    public String uploadImg(MultipartFile file, String uri) {
        // 获取文件扩展名
        String fileName = file.getOriginalFilename();
        String extension;
        if (fileName != null) {
            extension = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
        } else {
            throw new BaseException("文件为空");
        }
        // 检查扩展名是否在允许的范围内
        if (!isAllowedExtension(extension)) {
            System.out.println("我运行了");
            throw new PhotoException(MessageConstant.PHOTO_CLASS_FAILED);
        }

        try {
            String url = ossUtil.setOss(file, uri);
            if (url != null && !"".equals(url)) {
                this.addRedis(url);
            }
            return url;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static boolean isAllowedExtension(String extension) {
        for (String allowedExtension : ALLOWED_EXTENSIONS) {
            if (allowedExtension.equalsIgnoreCase(extension)) {
                return true;
            }
        }
        return false;
    }

    /**
     * A标记保存的图片
     *
     * @param url 标记的url
     */
    public void saveImages(String url) {
        if (url == null) {
            return;
        }
        redisTemplate.opsForHash().put(IMAGE_PREFIX + url, "statusCode", STATUS_ACTIVE);
    }

    /**
     * A存储url到redis里面
     *
     * @param url 图片地址
     * @author lechangxin
     */
    public void addRedis(String url) {
        if (url == null) {
            return;
        }
        String key = IMAGE_PREFIX + url;
        // 存储状态为有效
        HashMap<String, Object> valueMap = new HashMap<>();
        valueMap.put("statusCode", STATUS_UNACTIVE);
        valueMap.put("createTime", System.currentTimeMillis());
        redisTemplate.opsForHash().putAll(key, valueMap);
    }

    @Scheduled(cron = "0 */30 * * * ?")
    private void executeDailyTask() {
        log.info("我偷偷执行了删除无用图片");
        deleteExpiredImages();
    }

    /**
     * A删除所有状态为过期的图片
     */
    private void deleteExpiredImages() {
        Set<String> imageKeys = redisTemplate.keys(IMAGE_PREFIX + "*");
        int count = 0;
        if (imageKeys != null) {
            for (String key : imageKeys) {
                Map<Object, Object> imageData = redisTemplate.opsForHash().entries(key);
                Long createTime = null;
                createTime = (Long) imageData.get("createTime");
                if (createTime == null) {
                    redisTemplate.delete(key);
                    continue;
                }
                long currentTime = System.currentTimeMillis();
                long expirationThreshold = createTime + EXPIRATION_TIME;
                // 判断是否超过过期时间 超过可操作
                if (currentTime > expirationThreshold) {
                    // 超过过期时间，执行下一步逻辑
                    Integer statusCode = (Integer) imageData.get("statusCode");
                    System.out.println(statusCode);
                    if (statusCode != null && statusCode == STATUS_UNACTIVE) {
                        this.deleteUrl(key.substring(IMAGE_PREFIX.length()));
                    }
                    //处理后都删除
                    count++;
                    redisTemplate.delete(key);
                }

            }
            log.info("本次处理了{}张图片", count);
        }
    }

    /**
     * A根据链接删除oss图片
     *
     * @param url
     */
    public void deleteUrl(String url) {
        if (url == null) {
            return;
        }
        ossUtil.deleteOss(url);
    }

    /**
     * A图片集群上传回显
     *
     * @param files 图片们
     * @return url的json
     */
    @Override
    public String uploadImgs(List<MultipartFile> files, String uri) {
        List<String> results = new ArrayList<>();  // 用于存储每个文件的处理结果
        try {
            for (MultipartFile multipartFile : files) {
                String result = ossUtil.setOss(multipartFile, uri);
                results.add(result);
            }
            return JSON.toJSONString(results); // 返回 JSON 数组
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }
}
